The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 17
MANIFEST 03
META.yml 23
Makefile.PL 02
inc/Module/Install/AutoInstall.pm 19
inc/Module/Install/Base.pm 11
inc/Module/Install/Can.pm 11
inc/Module/Install/Fetch.pm 11
inc/Module/Install/Include.pm 11
inc/Module/Install/Makefile.pm 11
inc/Module/Install/Metadata.pm 11
inc/Module/Install/Win32.pm 11
inc/Module/Install/WriteAll.pm 11
inc/Module/Install.pm 37
lib/Catalyst/Action/Deserialize/Data/Serializer.pm 13
lib/Catalyst/Action/Deserialize/JSON.pm 13
lib/Catalyst/Action/Deserialize/View.pm 13
lib/Catalyst/Action/Deserialize/XML/Simple.pm 13
lib/Catalyst/Action/Deserialize/YAML.pm 13
lib/Catalyst/Action/Deserialize.pm 11
lib/Catalyst/Action/REST/ForBrowsers.pm 0113
lib/Catalyst/Action/REST.pm 2032
lib/Catalyst/Action/Serialize/Data/Serializer.pm 13
lib/Catalyst/Action/Serialize/JSON/XS.pm 13
lib/Catalyst/Action/Serialize/JSON.pm 13
lib/Catalyst/Action/Serialize/JSONP.pm 13
lib/Catalyst/Action/Serialize/View.pm 13
lib/Catalyst/Action/Serialize/XML/Simple.pm 13
lib/Catalyst/Action/Serialize/YAML/HTML.pm 13
lib/Catalyst/Action/Serialize/YAML.pm 13
lib/Catalyst/Action/Serialize.pm 13
lib/Catalyst/Action/SerializeBase.pm 13
lib/Catalyst/Controller/REST.pm 13
lib/Catalyst/Request/REST/ForBrowsers.pm 13
lib/Catalyst/Request/REST.pm 39
lib/Catalyst/TraitFor/Request/REST/ForBrowsers.pm 23
lib/Catalyst/TraitFor/Request/REST.pm 11
t/catalyst-action-deserialize.t 13
t/catalyst-action-rest-action-dispatch-for-browsers.t 052
t/catalyst-action-rest.t 13
t/catalyst-action-serialize-query.t 13
t/catalyst-action-serialize.t 12
t/catalyst-traitfor-request-rest.t 22
t/data-serializer.t 13
t/isa.t 12
t/json.t 12
t/jsonp.t 12
t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm 032
t/lib/Test/Rest.pm 110
t/view.t 13
t/xml-simple.t 13
t/yaml-html.t 13
t/yaml.t 13
53 files changed (This is a version diff) 74377
@@ -1,4 +1,10 @@
-Tue  11 Jan 2010 23:07:00 GMT - Release 0.88
+Mon  24 Jan 2011 21:57:42 GMT - Release 0.89
+  All classes are now made immutable. (Dave Rolsky)
+
+  Added a Catalyst::Action::REST::ForBrowsers class. This will try to dispatch
+  GET requests to a foo_GET_html method before trying foo_GET. (Dave Rolsky)
+
+Tue  11 Jan 2011 23:07:00 GMT - Release 0.88
   Fix documentation for overriding Serialize and Deserialize actions
   in Catalyst::Controller::REST.
 
@@ -20,6 +20,7 @@ lib/Catalyst/Action/Deserialize/View.pm
 lib/Catalyst/Action/Deserialize/XML/Simple.pm
 lib/Catalyst/Action/Deserialize/YAML.pm
 lib/Catalyst/Action/REST.pm
+lib/Catalyst/Action/REST/ForBrowsers.pm
 lib/Catalyst/Action/Serialize.pm
 lib/Catalyst/Action/Serialize/Data/Serializer.pm
 lib/Catalyst/Action/Serialize/JSON.pm
@@ -42,6 +43,7 @@ README
 t/broken/Catalyst/Action/Deserialize/Broken.pm
 t/broken/Catalyst/Action/Serialize/Broken.pm
 t/catalyst-action-deserialize.t
+t/catalyst-action-rest-action-dispatch-for-browsers.t
 t/catalyst-action-rest-action-dispatch.t
 t/catalyst-action-rest.t
 t/catalyst-action-serialize-accept.t
@@ -58,6 +60,7 @@ t/lib/Test/Action/Class.pm
 t/lib/Test/Action/Class/Sub.pm
 t/lib/Test/Catalyst/Action/REST.pm
 t/lib/Test/Catalyst/Action/REST/Controller/Actions.pm
+t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm
 t/lib/Test/Catalyst/Action/REST/Controller/Deserialize.pm
 t/lib/Test/Catalyst/Action/REST/Controller/Override.pm
 t/lib/Test/Catalyst/Action/REST/Controller/REST.pm
@@ -7,7 +7,7 @@ build_requires:
 configure_requires:
   ExtUtils::MakeMaker: 6.42
 distribution_type: module
-generated_by: 'Module::Install version 0.99'
+generated_by: 'Module::Install version 1.00'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -41,4 +41,5 @@ requires:
 resources:
   license: http://dev.perl.org/licenses/
   repository: git://git.shadowcat.co.uk/catagits/Catalyst-Action-REST.git
-version: 0.88
+version: 0.89
+x_authority: cpan:BOBTFISH
@@ -74,5 +74,7 @@ if ($Module::Install::AUTHOR) {
 
 repository 'git://git.shadowcat.co.uk/catagits/Catalyst-Action-REST.git';
 
+add_metadata( x_authority => 'cpan:BOBTFISH' );
+
 WriteAll;
 
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -48,6 +48,14 @@ sub auto_install {
     while (my ($mod, $ver) = splice(@requires, 0, 2)) {
         $seen{$mod}{$ver}++;
     }
+    my @build_requires = map @$_, map @$_, grep ref, $self->build_requires;
+    while (my ($mod, $ver) = splice(@build_requires, 0, 2)) {
+        $seen{$mod}{$ver}++;
+    }
+    my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires;
+    while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) {
+        $seen{$mod}{$ver}++;
+    }
 
     my @deduped;
     while (my ($mod, $ver) = splice(@features_require, 0, 2)) {
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 }
 
 # Suspend handler for "redefined" warnings
@@ -9,7 +9,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '0.99';
+	$VERSION = '1.00';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
@@ -230,8 +230,12 @@ sub preload {
 sub new {
 	my ($class, %args) = @_;
 
-    delete $INC{'FindBin.pm'};
-    require FindBin;
+	delete $INC{'FindBin.pm'};
+	{
+		# to suppress the redefine warning
+		local $SIG{__WARN__} = sub {};
+		require FindBin;
+	}
 
 	# ignore the prefix on extension modules built from top level.
 	my $base_path = Cwd::abs_path($FindBin::Bin);
@@ -9,7 +9,7 @@ use Safe;
 my $compartment = Safe->new;
 $compartment->permit_only( qw(padany null lineseq const pushmark list anonhash anonlist refgen leaveeval undef) );
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -61,4 +61,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use JSON;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -42,4 +42,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -5,11 +5,13 @@ use namespace::autoclean;
 
 extends 'Catalyst::Action';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -5,7 +5,7 @@ use namespace::autoclean;
 
 extends 'Catalyst::Action';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -44,4 +44,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use YAML::Syck;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -32,4 +32,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -7,7 +7,7 @@ extends 'Catalyst::Action::SerializeBase';
 use Module::Pluggable::Object;
 use MRO::Compat;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 has plugins => ( is => 'rw' );
@@ -0,0 +1,113 @@
+package Catalyst::Action::REST::ForBrowsers;
+
+use Moose;
+use namespace::autoclean;
+
+our $VERSION = '0.89';
+$VERSION = eval $VERSION;
+
+extends 'Catalyst::Action::REST';
+use Catalyst::Request::REST::ForBrowsers;
+
+sub BUILDARGS {
+    my $class  = shift;
+    my $config = shift;
+    Catalyst::Request::REST::ForBrowsers->_insert_self_into( $config->{class} );
+    return $class->SUPER::BUILDARGS( $config, @_ );
+}
+
+override dispatch => sub {
+    my $self = shift;
+    my $c    = shift;
+
+    my $req = $c->request();
+
+    return super()
+        unless $req->can('looks_like_browser')
+            && $req->looks_like_browser()
+            && uc $c->request()->method() eq 'GET';
+
+    my $controller  = $c->component( $self->class );
+    my $rest_method = $self->name() . '_GET_html';
+
+    if (   $controller->action_for($rest_method)
+        || $controller->can($rest_method) ) {
+
+        return $self->_dispatch_rest_method( $c, $rest_method );
+    }
+
+    return super();
+};
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+=head1 NAME
+
+Catalyst::Action::REST::ForBrowsers - Automated REST Method Dispatching that Accommodates Browsers
+
+=head1 SYNOPSIS
+
+    sub foo :Local :ActionClass('REST::ForBrowsers') {
+      ... do setup for HTTP method specific handlers ...
+    }
+
+    sub foo_GET : Private {
+      ... do something for GET requests ...
+    }
+
+    sub foo_GET_html : Private {
+      ... do something for GET requests from browsers ...
+    }
+
+    sub foo_PUT : Private {
+      ... do something for PUT requests ...
+    }
+
+=head1 DESCRIPTION
+
+This class subclasses L<Catalyst::Action::REST> to add an additional
+dispatching hook. If the request is a GET request I<and> the request looks
+like it comes from a browser, it tries to dispatch to a C<GET_html> method
+before trying to the C<GET> method instead. All other HTTP methods are
+dispatched in the same way.
+
+For example, in the synopsis above, calling GET on "/foo" from a browser will
+end up calling the C<foo_GET_html> method. If the request is I<not> from a
+browser, it will call C<foo_GET>.
+
+See L<Catalyst::Action::REST> for more details on dispatching details.
+
+=head1 METHODS
+
+=over 4
+
+=item dispatch
+
+This method overrides the default dispatch mechanism to the re-dispatching
+mechanism described above.
+
+=back
+
+=head1 SEE ALSO
+
+You likely want to look at L<Catalyst::Controller::REST>, which implements a
+sensible set of defaults for a controller doing REST.
+
+This class automatically adds the
+L<Catalyst::TraitFor::Request::REST::ForBrowsers> role to your request class.
+
+=head1 CONTRIBUTORS
+
+Dave Rolsky E<lt>autarch@urth.orgE<gt>
+
+=head1 COPYRIGHT
+
+Copyright the above named AUTHOR and CONTRIBUTORS
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
@@ -10,14 +10,14 @@ use Catalyst::Controller::REST;
 
 BEGIN { require 5.008001; }
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
-sub new {
-  my $class  = shift;
-  my $config = shift;
-  Catalyst::Request::REST->_insert_self_into( $config->{class} );
-  return $class->next::method($config, @_);
+sub BUILDARGS {
+    my $class  = shift;
+    my $config = shift;
+    Catalyst::Request::REST->_insert_self_into( $config->{class} );
+    return $class->SUPER::BUILDARGS($config, @_);
 }
 
 =head1 NAME
@@ -85,34 +85,44 @@ sub dispatch {
     my $self = shift;
     my $c    = shift;
 
-    my $controller = $c->component( $self->class );
     my $rest_method = $self->name . "_" . uc( $c->request->method );
 
+    return $self->_dispatch_rest_method( $c, $rest_method );
+}
+
+sub _dispatch_rest_method {
+    my $self        = shift;
+    my $c           = shift;
+    my $rest_method = shift;
+
+    my $controller = $c->component( $self->class );
+
     my ($code, $name);
 
     # Common case, for foo_GET etc
     if ( $code = $controller->action_for($rest_method) ) {
         $c->execute( $self->class, $self, @{ $c->req->args } ); # Execute normal 'foo' action.
         return $c->forward( $code,  $c->req->args ); # Forward to foo_GET if it's an action
-     }
-     elsif ($code = $controller->can($rest_method)) {
-        # Exceute normal action
+    }
+    elsif ($code = $controller->can($rest_method)) {
+        # Execute normal action
         $c->execute( $self->class, $self, @{ $c->req->args } );
         $name = $rest_method; # Stash name and code to run 'foo_GET' like an action below.
     }
 
     # Generic handling for foo_OPTIONS
-    if (!$code && $c->request->method eq "OPTIONS") {
-        $name = $rest_method;
-        $code = sub { $self->_return_options($self->name, @_) };
-    }
-
-    # Otherwise, not implemented.
     if (!$code) {
-        $name = $self->name . "_not_implemented";
-        $code = $controller->can($name) # User method
-            # Generic not implemented
-            || sub { $self->_return_not_implemented($self->name, @_) };
+        if ( $c->request->method eq "OPTIONS") {
+            $name = $rest_method;
+            $code = sub { $self->_return_options($self->name, @_) };
+        }
+        else {
+            # Otherwise, not implemented.
+            $name = $self->name . "_not_implemented";
+            $code = $controller->can($name) # User method
+                # Generic not implemented
+                || sub { $self->_return_not_implemented($self->name, @_) };
+        }
     }
 
     # localise stuff so we can dispatch the action 'as normal, but get
@@ -151,6 +161,8 @@ sub _return_not_implemented {
           . $c->uri_for( $method_name ) );
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
 
 =back
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use Data::Serializer;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -34,4 +34,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action::Serialize::JSON';
 use JSON::XS ();
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub _build_encoder {
@@ -14,4 +14,6 @@ sub _build_encoder {
    return JSON::XS->new->convert_blessed;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use JSON ();
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 has encoder => (
@@ -39,4 +39,6 @@ sub serialize {
     $self->encoder->encode( $data );
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -4,7 +4,7 @@ use namespace::autoclean;
 
 extends 'Catalyst::Action::Serialize::JSON';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 after 'execute' => sub {
@@ -28,4 +28,6 @@ after 'execute' => sub {
   }
 };
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -4,7 +4,7 @@ use namespace::autoclean;
 
 extends 'Catalyst::Action';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -37,4 +37,6 @@ sub execute {
     }
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -5,7 +5,7 @@ use namespace::autoclean;
 
 extends 'Catalyst::Action';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -32,4 +32,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -7,7 +7,7 @@ extends 'Catalyst::Action';
 use YAML::Syck;
 use URI::Find;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -45,4 +45,6 @@ sub execute {
     return 1;
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -6,7 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use YAML::Syck;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 sub execute {
@@ -29,4 +29,6 @@ sub serialize {
     Dump($data);
 }
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -7,7 +7,7 @@ extends 'Catalyst::Action::SerializeBase';
 use Module::Pluggable::Object;
 use MRO::Compat;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 has _encoders => (
@@ -64,6 +64,8 @@ sub execute {
 
 __PACKAGE__->meta->make_immutable;
 
+1;
+
 =head1 NAME
 
 Catalyst::Action::Serialize - Serialize Data in a Response
@@ -8,7 +8,7 @@ use Module::Pluggable::Object;
 use Catalyst::Request::REST;
 use Catalyst::Utils ();
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 after BUILDARGS => sub {
@@ -157,6 +157,8 @@ sub _serialize_bad_request {
 
 __PACKAGE__->meta->make_immutable;
 
+1;
+
 =head1 NAME
 
 Catalyst::Action::SerializeBase - Base class for Catalyst::Action::Serialize and Catlayst::Action::Deserialize.
@@ -2,7 +2,7 @@ package Catalyst::Controller::REST;
 use Moose;
 use namespace::autoclean;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 =head1 NAME
@@ -623,4 +623,6 @@ You may distribute this code under the same terms as Perl itself.
 
 =cut
 
+__PACKAGE__->meta->make_immutable;
+
 1;
@@ -3,12 +3,14 @@ use Moose;
 
 use namespace::autoclean;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 extends 'Catalyst::Request::REST';
 with 'Catalyst::TraitFor::Request::REST::ForBrowsers';
 
+sub _related_role { 'Catalyst::TraitFor::Request::REST::ForBrowsers' }
+
 __PACKAGE__->meta->make_immutable;
 
 1;
@@ -7,7 +7,7 @@ use namespace::autoclean;
 extends 'Catalyst::Request';
 with 'Catalyst::TraitFor::Request::REST';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 # Please don't take this as a recommended way to do things.
@@ -23,14 +23,15 @@ sub _insert_self_into {
   my $req_class = $app->request_class;
   return if $req_class->isa($class);
   my $req_class_meta = Moose->init_meta( for_class => $req_class );
-  return if $req_class_meta->does_role('Catalyst::TraitFor::Request::REST');
+  my $role = $class->_related_role;
+  return if $req_class_meta->does_role($role);
   if ($req_class eq 'Catalyst::Request') {
     $app->request_class($class);
   }
   else {
       my $meta = Moose::Meta::Class->create_anon_class(
           superclasses => [$req_class],
-          roles => ['Catalyst::TraitFor::Request::REST'],
+          roles => [$role],
           cache => 1
       );
       $meta->_add_meta_method('meta');
@@ -38,7 +39,12 @@ sub _insert_self_into {
   }
 }
 
+sub _related_role { 'Catalyst::TraitFor::Request::REST' }
+
 __PACKAGE__->meta->make_immutable;
+
+1;
+
 __END__
 
 =head1 NAME
@@ -4,7 +4,7 @@ use namespace::autoclean;
 
 with 'Catalyst::TraitFor::Request::REST';
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 has _determined_real_method => (
@@ -175,7 +175,8 @@ If the client provides an Accept header and accepts either "text/html" or
 
 =item *
 
-If it provides an Accept header of any sort, it is I<not> a browser.
+If it provides an Accept header of any sort that doesn't match one of the
+above criteria, it is I<not> a browser.
 
 =item *
 
@@ -3,7 +3,7 @@ use Moose::Role;
 use HTTP::Headers::Util qw(split_header_words);
 use namespace::autoclean;
 
-our $VERSION = '0.88';
+our $VERSION = '0.89';
 $VERSION = eval $VERSION;
 
 has [qw/ data accept_only /] => ( is => 'rw' );
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 5;
+use Test::More;
 use YAML::Syck;
 use FindBin;
 
@@ -26,3 +26,5 @@ my $ures = request($ut->put( url => $url, data => Dump({ kitty => "LouLou" })));
 is ($bres->code, 415, 'GET on unknown Content-Type returns 415');
 
 1;
+
+done_testing;
@@ -0,0 +1,52 @@
+use strict;
+use warnings;
+use Test::More;
+use FindBin;
+
+use lib ( "$FindBin::Bin/lib", "$FindBin::Bin/../lib" );
+use Test::Rest;
+
+my $t = Test::Rest->new( 'content_type' => 'text/plain' );
+
+use_ok 'Catalyst::Test', 'Test::Catalyst::Action::REST';
+
+my $url = '/actionsforbrowsers/for_browsers';
+
+foreach my $method (qw(GET POST)) {
+    my $run_method = lc($method);
+    my $result     = "something $method";
+    my $res;
+    if ( $method eq 'GET' ) {
+        $res = request( $t->$run_method( url => $url ) );
+    } else {
+        $res = request(
+            $t->$run_method(
+                url  => $url,
+                data => '',
+            )
+        );
+    }
+    ok( $res->is_success, "$method request succeeded" );
+    is(
+        $res->content,
+        "$method",
+        "$method request had proper response"
+    );
+}
+
+my $res = request(
+    $t->get(
+        url     => $url,
+        headers => { Accept => 'text/html' },
+    )
+);
+
+ok( $res->is_success, "GET request succeeded (client looks like browser)" );
+is(
+    $res->content,
+    "GET_html",
+    "GET request had proper response (client looks like browser)"
+);
+
+done_testing;
+
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 18;
+use Test::More;
 use FindBin;
 
 use lib ( "$FindBin::Bin/lib", "$FindBin::Bin/../lib" );
@@ -54,3 +54,5 @@ is(
 );
 
 1;
+
+done_testing;
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 3; 
+use Test::More;
 use FindBin;
 
 use lib ("$FindBin::Bin/lib", "$FindBin::Bin/../lib", "$FindBin::Bin/broken");
@@ -22,3 +22,5 @@ EOH
 is( $res->content, $data, "Request returned proper data");
 
 1;
+
+done_testing;
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+
 use Test::More 0.88;
 use Data::Serializer;
 use FindBin;
@@ -35,6 +36,7 @@ $res2 = request($t->get(url => '/serialize/test_second'));
 ok( $res2->is_success, 'request succeeded (deprecated config)' );
 is( $res2->content, "{'lou' => 'is my cat'}", "request returned proper data");
 
+
 $res = request($t->get(url => '/serialize/empty_serialized'));
 is $res->content, q[{'foo' => 'bar'}], 'normal case ok';
 ok $res->header('Content-Length'), 'set content-length when we serialize';
@@ -48,4 +50,3 @@ is $res->content, '', "body explicitly set to '' results in '' content";
 ok !$res->header('Content-Length'), "body explicitly set to '' - no automatic content-length";
 
 done_testing;
-
@@ -182,8 +182,8 @@ for my $class ( $anon_class, 'Catalyst::Request::REST' ) {
   $ENV{CATALYST_DEBUG} = 0;
   my $test = 'Test::Catalyst::Action::REST';
   use_ok $test;
-  is($test->request_class, 'Catalyst::Request::REST',
-    'Request::REST took over for Request');
+  ok($test->request_class->does('Catalyst::TraitFor::Request::REST'),
+    'Request does Catalyst::TraitFor::Request::REST');
 
   my $meta = Moose::Meta::Class->create_anon_class(
       superclasses => ['Catalyst::Request'],
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 31;
+use Test::More;
 use FindBin;
 
 use lib ( "$FindBin::Bin/lib", "$FindBin::Bin/../lib" );
@@ -78,3 +78,5 @@ foreach my $content_type (keys(%ctypes)) {
 }
 
 1;
+
+done_testing;
@@ -4,7 +4,7 @@ use warnings;
 use FindBin qw/$Bin/;
 use lib "$Bin/lib";
 
-use Test::More tests => 5;
+use Test::More;
 
 use Test::Catalyst::Action::REST;
 
@@ -18,3 +18,4 @@ isa_ok($action, 'Catalyst::Action::REST');
 ok(!$action->isa('Catalyst'));
 ok(!$action->isa('Catalyst::Controller'));
 
+done_testing;
@@ -10,7 +10,6 @@ use utf8;
 eval 'use JSON 2.12';
 plan skip_all => 'Install JSON 2.12 or later to run this test' if ($@);
 
-plan tests => 11;
 
 use_ok 'Catalyst::Test', 'Test::Serialize';
 
@@ -47,3 +46,5 @@ for ('text/x-json', 'application/json') {
 }
 
 1;
+
+done_testing;
@@ -10,7 +10,6 @@ use utf8;
 eval 'use JSON 2.12';
 plan skip_all => 'Install JSON 2.12 or later to run this test' if ($@);
 
-plan tests => 7;
 
 use_ok 'Catalyst::Test', 'Test::Serialize', 'Catalyst::Action::Serialize::JSON';
 
@@ -28,3 +27,5 @@ for ('text/javascript','application/x-javascript','application/javascript') {
 }
 
 1;
+
+done_testing;
@@ -0,0 +1,32 @@
+package Test::Catalyst::Action::REST::Controller::ActionsForBrowsers;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends qw/Catalyst::Controller::REST/ }
+
+sub begin {}  # Don't need serialization..
+
+sub for_browsers : Local : ActionClass('REST::ForBrowsers') {
+    my ( $self, $c ) = @_;
+    $c->res->header('X-Was-In-TopLevel', 1);
+}
+
+sub for_browsers_GET : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('GET');
+}
+
+sub for_browsers_GET_html : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('GET_html');
+}
+
+sub for_browsers_POST : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('POST');
+}
+
+sub end : Private {} # Don't need serialization..
+
+1;
+
@@ -26,8 +26,15 @@ sub new {
         my $sub = lc($method);
         *$sub = sub {
             my $self = shift;
-            my %p    = validate( @_, { url => { type => SCALAR }, }, );
+            my %p = validate(
+                @_,
+                {
+                    url     => { type => SCALAR },
+                    headers => { type => HASHREF, default => {} },
+                },
+            );
             my $req  = HTTP::Request->new( "$method" => $p{'url'} );
+            $req->header( $_ => $p{headers}{$_} ) for keys %{ $p{headers} };
             $req->content_type( $self->{'content_type'} );
             return $req;
         };
@@ -44,9 +51,11 @@ sub new {
                 {
                     url  => { type => SCALAR },
                     data => 1,
+                    headers => { type => HASHREF, default => {} },
                 },
             );
             my $req = HTTP::Request->new( "$method" => $p{'url'} );
+            $req->header( $_ => $p{headers}{$_} ) for keys %{ $p{headers} };
             $req->content_type( $self->{'content_type'} );
             $req->content_length(
                 do { use bytes; length( $p{'data'} ) }
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 6;
+use Test::More;
 use FindBin;
 
 use lib ( "$FindBin::Bin/lib", "$FindBin::Bin/../lib" );
@@ -25,3 +25,5 @@ ok (! $res->is_success, 'View errors result in failure');
 like( $res->content, qr/don't know how/, 'The error looks okay');
 
 1;
+
+done_testing;
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 5;
+use Test::More;
 use FindBin;
 
 use lib ("$FindBin::Bin/lib", "$FindBin::Bin/../lib");
@@ -33,3 +33,5 @@ SKIP: {
 };
 
 1;
+
+done_testing;
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 4;
+use Test::More;
 use YAML::Syck;
 use FindBin;
 
@@ -30,3 +30,5 @@ SKIP: {
 
 }
 1;
+
+done_testing;
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 5; 
+use Test::More;
 use FindBin;
 
 use lib ("$FindBin::Bin/lib", "$FindBin::Bin/../lib");
@@ -32,3 +32,5 @@ SKIP: {
 };
 
 1;
+
+done_testing;